package sctu.edu.java.year2016.team02.project.pc.problem;

import sctu.edu.java.year2016.team02.project.Problem;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Eoly on 2016/6/16.
 */
//该类大多方法为想服务端传送请求，获得服务端对数据库操作结果
public class PcProblem implements Problem {
    //私有储存变量
    private String mainMessage;
    private String detailMessage;
    private String solveResult;
    private String username;
    private String ipAddress;
    private String userNameAndIpAddress;
    private String keyToRE;
    private String tipMessage;

    //公开静态变量
    public static Socket socket = null;
    public static String ipNetAddress = "127.0.0.1";
    public static int port=8888;

    //各种操作编号
    public static final int SELECT = 4;
    public static final int DELETE = 5;
    public static final int UPDATE_STRING = 6;
    public static final int UPDATE_INT = 7;
    public static final int INSERT = 8;
    public static final int INSERT_KEY = 9;

    public PcProblem() {

    }
    //获得套接字并连接远程服务端
    public static Socket getSocket() {
        if(socket!=null){
            try {
                socket.close();
            } catch (IOException e) {
                SocketListener.outWorryMessage(e.getMessage(), "套接字关闭失败");
            }
        }
        SocketListener.connectedState("正在连接....");
        return socket;
    }

    @Override
    //提交数据
    public void inHand() throws SQLException {
        while (socket == null || socket.isClosed()) getSocket();
        ipAddress = socket.getLocalAddress().toString();
        userNameAndIpAddress = ipAddress;
        keyToRE = userNameAndIpAddress + mainMessage;
        String[] name = {"UserNameAndIpAddress", "KeyToRE", "MainMessage", "DetailMessage"};
        String[] value = {userNameAndIpAddress, keyToRE, mainMessage, detailMessage};
        if (!insert("Problem", name, value, 1)) {
            tipMessage = "该内容及关键字重复添加！";
            System.out.println(tipMessage);
        } else {
            tipMessage = "提交成功！";
            System.out.println(tipMessage);
        }
    }

    //查找数据
    @Override
    public List<Object[]> seeking() throws SQLException {
        String[] filename = {"MainMessage", "DetailMessage"};
        String[] value = {mainMessage, mainMessage};
        return select("Problem", filename, value, true);
    }

    //查找数据，有三个选择
    @Override
    public List<Object[]> seeking(int option) throws SQLException {
        if(option!=2) {
            String[] filename = {"SolvedOrNot"};
            String[] value = {String.valueOf(option)};
            return select("Problem",filename,value,true);
        }else {
            String[] filename = {""};
            return select("Problem", filename, filename, true);
        }
    }

    //判断是否解决
    public static boolean isSolved(Object isSol) {
        return (int)isSol==1;
    }

    //传输数据到服务端进行更新操作（value为String型）
    public static void update(String TableName, String name, String key, String keyfield, String value) throws SQLException {
        List list = new ArrayList<>();
        list.add(0, TableName);
        list.add(1, name);
        list.add(2, key);
        list.add(3, keyfield);
        list.add(4, value);
        try {
            if (isRightAction(UPDATE_STRING)) {
                Output(list);
                String message =(String)Input();
                System.out.println("服务器："+message);
            }
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
    }

    //传输数据到服务端进行更新操作（value为int型）
    public static void update(String TableName, String name, String key, String keyfield, int value) throws SQLException {
        List list = new ArrayList<>();
        list.add(0, TableName);
        list.add(1, name);
        list.add(2, key);
        list.add(3, keyfield);
        list.add(4, value);
        try {
            if (isRightAction(UPDATE_INT)) {
                Output(list);
                String message =(String)Input();
                System.out.println("服务器："+message);
            }
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
    }

    //传输数据到服务端进行插入操作，并返回是否操作成功
    //TableName：表名；name：每列关键字；value：对应关键字插入值；
    public static boolean insert(String TableName, String[] name, String[] value) throws SQLException {
        List list = new ArrayList<>();
        list.add(0, TableName);
        list.add(1, name);
        list.add(2, value);
        try {
            if (isRightAction(INSERT)) {
                Output(list);
                return (boolean) Input();
            }
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
        return false;
    }

    //传输数据到服务端进行插入操作（注明key的位置），并返回是否操作成功
    //TableName：表名；name：每列关键字；value：对应关键字插入值；key：表的主关键字在name的索引号位置；
    public static boolean insert(String TableName, String[] name, String[] value, int keyindex) throws SQLException {
        List list = new ArrayList<>();
        list.add(0, TableName);
        list.add(1, name);
        list.add(2, value);
        list.add(3, keyindex);
        try {
            if (isRightAction(INSERT_KEY)) {
                Output(list);
                return (boolean) Input();
            }
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
        return false;
    }

    //传输数据到服务端进行查找操作，并返回一个从服务端获得的List集合
    //TableName：表名；fieldname：每列关键字；value：对应关键字插入值；isLike：是否为模糊查找；
    public static List<Object[]> select(String TableName, String[] fieldname, String[] value, boolean isLike) throws SQLException {
        List list = new ArrayList<>();
        list.add(0, TableName);
        list.add(1, fieldname);
        list.add(2, value);
        list.add(isLike);
        try {
            if (isRightAction(SELECT)) {
                Output(list);
                return (List<Object[]>) Input();
            }
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
        System.out.println("查找失败");
        return null;
    }

    //传输数据到服务端进行删除操作
    //key：表主关键字；TableName：表名；
    public static void delete(String key, String TableName) throws SQLException {
        try {
            List<String> list = new ArrayList<>();
            list.add(0, key);
            list.add(1, TableName);
            if (isRightAction(DELETE)) {
                Output(list);
                String message = (String) Input();
                System.out.println("服务器：" + message);
            }
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
    }

    //判断和服务端是否正确连接
    private static boolean isRightAction(int option) {
        while (socket == null || socket.isClosed()) getSocket();
        try {
            Output(option);
            int temp = (int) Input();
            return temp == option;
        } catch (IOException e) {
            SocketListener.outWorryMessage(e.getMessage(), "输入输出流错误");
            SocketListener.connectedState(e.getMessage());
        }
        return false;
    }

    //与服务端的输入流
    private static Object Input(){
        if (socket.isConnected() && !socket.isClosed()) {
            ObjectInputStream input = null;
            try {
                input = new ObjectInputStream(socket.getInputStream());
                return input.readObject();
            } catch (IOException e) {
                SocketListener.outErrorMessage(e.getMessage(), "获取输入流失败");
            } catch (ClassNotFoundException e) {
                SocketListener.outErrorMessage(e.getMessage(),"获取服务器响应失败");
            }
        }
        return null;
    }

    //与服务端的输出流
    private static void Output(Object obj) throws IOException {
        if (socket.isConnected() && !socket.isClosed()) {
            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
            output.writeObject(obj);
            output.flush();
        }
    }

    public String getMainMessage() {
        return mainMessage;
    }

    public void setMainMessage(String mainMessage) {
        this.mainMessage = mainMessage;
    }

    public String getDetailMessage() {
        return detailMessage;
    }

    public void setDetailMessage(String detailMessage) {
        this.detailMessage = detailMessage;
    }

    public String getSolveResult() {
        return solveResult;
    }

    public void setSolveResult(String solveResult) {
        this.solveResult = solveResult;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getIpAddress() {
        return ipAddress;
    }

    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }

    public String getUserNameAndIpAddress() {
        return userNameAndIpAddress;
    }

    public void setUserNameAndIpAddress(String userNameAndIpAddress) {
        this.userNameAndIpAddress = userNameAndIpAddress;
    }

    public String getKeyToRE() {
        return keyToRE;
    }

    public void setKeyToRE(String keyToRE) {
        this.keyToRE = keyToRE;
    }

    public String getTipMessage() {
        return tipMessage;
    }

    public void setTipMessage(String tipMessage) {
        this.tipMessage = tipMessage;
    }
}
